#include "ccp903_rsa2048.h"
#include "sec_common.h"
#include "e_os.h"
#include "hard.h"
#include <openssl/modes.h>
int ccp903_rsa2048_keygen(int ccp903_fd, unsigned char *rsa_e, unsigned int rsa_e_len, unsigned char *rsa_d, unsigned int *rsa_d_len, unsigned char *rsa_n, unsigned int *rsa_n_len, unsigned char *rsa_p, unsigned int *rsa_p_len, unsigned char *rsa_q, unsigned int *rsa_q_len, unsigned char *rsa_dp, unsigned int *rsa_dp_len, unsigned char *rsa_dq, unsigned int *rsa_dq_len, unsigned char *rsa_qInv, unsigned int *rsa_qInv_len)
{
	struct rsa2048_keygen_api capi =
	{
		.field = 0,
		.rsa_random_bit = 8*256,
		.fixed = 1,//pubkey   fixed 0x10001
		.crt = 1, //fast priv
	};
//	printf("rsa start\n");
	memcpy(capi.rsa_e, rsa_e, 256);

    	ioctl(ccp903_fd, _IOC(0x00, CCP903T_PCIE_MAGIC, ACLASS_RSA_GENKEY, sizeof(capi)), &capi);
    	if(capi.field != 0)
        	return 0;
//	printf("rsa success\n");
	memcpy(rsa_e, capi.rsa_e, 256);
	memcpy(rsa_d, capi.rsa_d, 256);
	memcpy(rsa_n, capi.rsa_n, 256);
	memcpy(rsa_p, capi.rsa_p, 256);
	memcpy(rsa_q, capi.rsa_q, 256);
	memcpy(rsa_dp, capi.rsa_dp, 256);
	memcpy(rsa_dq, capi.rsa_dq, 256);
	memcpy(rsa_qInv, capi.rsa_qInv, 256);
	*rsa_d_len = 256;
	*rsa_n_len = 256;
	*rsa_p_len = 256;
	*rsa_q_len = 256;
	*rsa_dp_len = 256;
	*rsa_dq_len = 256;
	*rsa_qInv_len = 256;

	return 1;
}

int ccp903_rsa2048_encrpy(int ccp903_fd, unsigned char *rsa_e, unsigned int rsa_e_len, unsigned char *rsa_n, unsigned int rsa_n_len, unsigned char *rsa_plain, unsigned int rsa_plain_len, unsigned char *rsa_c, unsigned int *rsa_c_len)
{
	struct rsa2048_enc_api capi =
	{
		.mode = 0x6,//MOD_EXP
		.n_len = 256,
		.a_len = 256,
		.e_len = 256,
	};
	memcpy(capi.rsa_e, rsa_e, rsa_e_len);
	memcpy(capi.rsa_n, rsa_n, rsa_n_len);
	memcpy(capi.rsa_plain, rsa_plain, rsa_plain_len);

        ioctl(ccp903_fd, _IOC(0x00, CCP903T_PCIE_MAGIC, ACLASS_RSA_PUB_BIG, sizeof(capi)), &capi);
    	while((capi.mode & PKHA_DONE_MASK) == 0);//wait for drive

	memcpy(rsa_c, capi.rsa_c, 256);
	*rsa_c_len = 256;
	return 1;
}
void memcpy_c(unsigned char *out, unsigned char *src, unsigned int len)
{
	unsigned int i;
	for(i=0; i<len; i++)
		out[i] = src[len-i-1];
}

int ccp903_rsa2048_decrypt_crt(int ccp903_fd, unsigned char *rsa_c, unsigned int rsa_c_len, unsigned char *rsa_n, unsigned int rsa_n_len, unsigned char *rsa_p, unsigned int rsa_p_len, unsigned char *rsa_q, unsigned int rsa_q_len, unsigned char *rsa_dp, unsigned int rsa_dp_len, unsigned char *rsa_dq, unsigned int rsa_dq_len, unsigned char *rsa_qInv, unsigned int rsa_qInv_len, unsigned char *rsa_plain, unsigned int *rsa_plain_len)
{
	struct rsa2048_dec_crt_api capi =
	{
		.mode = 0x06,//MOD_EXP
		.e_len = 256,
		.n_len = 256,
		.a_len = 256,
	};


	memcpy(capi.rsa_n, rsa_n, rsa_n_len);
	memcpy(capi.rsa_c, rsa_c, rsa_c_len);
	memcpy(capi.rsa_p, rsa_p, rsa_p_len);
	memcpy(capi.rsa_q, rsa_q, rsa_q_len);
	memcpy(capi.rsa_dp, rsa_dp, rsa_dp_len);
	memcpy(capi.rsa_dq, rsa_dq, rsa_dq_len);
	memcpy(capi.rsa_qInv, rsa_qInv, rsa_qInv_len);
/*
    int i;
    printf("rsa2048_p: ");
    for(i = 0; i < 256; i++)
    {
	printf("%x ",rsa_p[i]);
    }
    printf("\n");
    printf("rsa2048_capi.rsa_p: ");
    for(i = 0; i < 256; i++)
    {
	printf("%x ",capi.rsa_p[i]);
    }
    printf("\n");
    printf("rsa2048_q: ");
    for(i = 0; i < 256; i++)
    {
	printf("%x ",rsa_q[i]);
    }
    printf("\n");
    printf("rsa2048_capi.rsa_q: ");
    for(i = 0; i < 256; i++)
    {
	printf("%x ",capi.rsa_q[i]);
    }
    printf("\n");
*/
	ioctl(ccp903_fd, _IOC(0x00, CCP903T_PCIE_MAGIC, ACLASS_RSA_PRIV_CRT, sizeof(capi)), &capi);
    	while((capi.mode & PKHA_DONE_MASK) == 0);//wait for drive

	memcpy(rsa_plain,capi.rsa_plain,256);
	*rsa_plain_len = 256;

	return 1;
}
int ccp903_rsa2048_decrypt_nocrt(int ccp903_fd, unsigned char *rsa_c, unsigned int rsa_c_len, unsigned char *rsa_n, unsigned int rsa_n_len, unsigned char *rsa_d, unsigned int rsa_d_len, unsigned char *rsa_plain, unsigned int *rsa_plain_len)
{
	struct rsa2048_dec_nocrt_api capi =
	{
		.mode = 0x06,//MOD_EXP
		.e_len = 256,
		.n_len = 256,
		.a_len = 256,
	};
	memcpy(capi.rsa_n, rsa_n, rsa_n_len);
	memcpy(capi.rsa_c, rsa_c, rsa_c_len);
	memcpy(capi.rsa_d, rsa_d, rsa_d_len);

	ioctl(ccp903_fd, _IOC(0x00, CCP903T_PCIE_MAGIC, ACLASS_RSA_PRIV_BIG, sizeof(capi)), &capi);
    	while((capi.mode & PKHA_DONE_MASK) == 0);//wait for drive

	memcpy(rsa_plain,capi.rsa_plain,256);
	*rsa_plain_len = 256;

	return 1;
}

int ccp903_rsa2048_sign_crt(int ccp903_fd, unsigned char *rsa_plain, unsigned int rsa_plain_len, unsigned char *rsa_n, unsigned int rsa_n_len, unsigned char *rsa_p, unsigned int rsa_p_len, unsigned char *rsa_q, unsigned int rsa_q_len, unsigned char *rsa_dp, unsigned int rsa_dp_len, unsigned char *rsa_dq, unsigned int rsa_dq_len, unsigned char *rsa_qInv, unsigned int rsa_qInv_len, unsigned char *rsa_sign, unsigned int *rsa_sign_len)
{
	struct rsa2048_sign_crt_api capi =
	{
		.mode = 0x06,//MOD_EXP
		.e_len = 256,
		.n_len = 256,
		.a_len = 256,
	};
	memcpy(capi.rsa_n, rsa_n, rsa_n_len);
	memcpy(capi.rsa_plain, rsa_plain, rsa_plain_len);
	memcpy(capi.rsa_p, rsa_p, rsa_p_len);
	memcpy(capi.rsa_q, rsa_q, rsa_q_len);
	memcpy(capi.rsa_dp, rsa_dp, rsa_dp_len);
	memcpy(capi.rsa_dq, rsa_dq, rsa_dq_len);
	memcpy(capi.rsa_qInv, rsa_qInv, rsa_qInv_len);

	ioctl(ccp903_fd, _IOC(0x00, CCP903T_PCIE_MAGIC, ACLASS_RSA_PRIV_CRT, sizeof(capi)), &capi);
    	while((capi.mode & PKHA_DONE_MASK) == 0);//wait for drive

	memcpy(rsa_sign,capi.rsa_sign,256);
	*rsa_sign_len = 256;

	return 1;
}

int ccp903_rsa2048_sign_nocrt(int ccp903_fd, unsigned char *rsa_plain, unsigned int rsa_plain_len, unsigned char *rsa_n, unsigned int rsa_n_len, unsigned char *rsa_d, unsigned int rsa_d_len, unsigned char *rsa_sign, unsigned int *rsa_sign_len)
{
	struct rsa2048_sign_nocrt_api capi =
	{
		.mode = 0x06,//MOD_EXP
		.e_len = 256,
		.n_len = 256,
		.a_len = 256,
	};
	memcpy(capi.rsa_n, rsa_n, rsa_n_len);
	memcpy(capi.rsa_plain, rsa_plain, rsa_plain_len);
	memcpy(capi.rsa_d, rsa_d, rsa_d_len);

	ioctl(ccp903_fd, _IOC(0x00, CCP903T_PCIE_MAGIC, ACLASS_RSA_PRIV_BIG, sizeof(capi)), &capi);
    	while((capi.mode & PKHA_DONE_MASK) == 0);//wait for drive

	memcpy(rsa_sign,capi.rsa_sign,256);
	*rsa_sign_len = 256;

	return 1;
}

int ccp903_rsa2048_verify(int ccp903_fd, unsigned char *rsa_plain, unsigned int rsa_plain_len, unsigned char *rsa_e, unsigned int rsa_e_len, unsigned char *rsa_n, unsigned int rsa_n_len, unsigned char *rsa_signed, unsigned int rsa_signed_len, unsigned char *rsa_ver_plain, unsigned int *rsa_ver_plain_len)
{
	struct rsa2048_ver_api capi =
	{
		.mode = 0x6,//MOD_EXP
		.n_len = 256,
		.a_len = 256,
		.e_len = 256,
	};
	memcpy(capi.rsa_e, rsa_e, rsa_e_len);
	memcpy(capi.rsa_n, rsa_n, rsa_n_len);
	memcpy(capi.rsa_signed, rsa_signed, rsa_signed_len);

        ioctl(ccp903_fd, _IOC(0x00, CCP903T_PCIE_MAGIC, ACLASS_RSA_PUB_BIG, sizeof(capi)), &capi);
    	while((capi.mode & PKHA_DONE_MASK) == 0);//wait for drive

	memcpy(rsa_ver_plain, capi.rsa_ver_plain, 256);
	*rsa_ver_plain_len = 256;

	return 1;

}
